home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / Utils / SWFastLine.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  57.3 KB  |  2,097 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    SWFastLine.c
  3. //
  4. //    Everything except BlitLine68kAsm is by Vern Jensen, 12/21/98. 
  5. //    BlitLine68kAsm is by Oleg Doperchuk, and is believed to be in the public domain.
  6. //    Thanks to Alex Ni for getting BlitLine68kAsm to compile under CodeWarrior.
  7. ///--------------------------------------------------------------------------------------
  8.  
  9. #include <SWFastLine.h>
  10.  
  11. #define SIGN(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
  12. #define ABS(x) ((x) < 0 ? -(x) : (x))
  13.  
  14.  
  15. #if !SW_PPC
  16. ///--------------------------------------------------------------------------------------
  17. //    SWDrawLine68kAsm - warning, no clipping is performed by this function!
  18. ///--------------------------------------------------------------------------------------
  19.  
  20. SW_FUNC void SWDrawLine68kAsm(
  21.     FramePtr dstFrameP, 
  22.     Point srcPoint, 
  23.     Point dstPoint, 
  24.     Byte color)
  25. {
  26.     Ptr                baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[0];
  27.     unsigned long    rowBytes = dstFrameP->frameRowBytes;
  28.     
  29.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  30.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  31.     SW_ASSERT(srcPoint.h >= dstFrameP->frameRect.left && srcPoint.h < dstFrameP->frameRect.right);
  32.     SW_ASSERT(srcPoint.v >= dstFrameP->frameRect.top && srcPoint.v < dstFrameP->frameRect.bottom);
  33.     SW_ASSERT(dstPoint.h >= dstFrameP->frameRect.left && dstPoint.h < dstFrameP->frameRect.right);
  34.     SW_ASSERT(dstPoint.v >= dstFrameP->frameRect.top && dstPoint.v < dstFrameP->frameRect.bottom);
  35.     
  36.     START_32_BIT_MODE
  37.     
  38.     BlitLine68kAsm(baseAddr, rowBytes, srcPoint.h, dstPoint.h, srcPoint.v, dstPoint.v, color);
  39.  
  40.     END_32_BIT_MODE
  41. }
  42. #endif
  43.  
  44.  
  45. ///--------------------------------------------------------------------------------------
  46. //  SWDrawLine
  47. ///--------------------------------------------------------------------------------------
  48.  
  49. SW_FUNC void SWDrawLine(
  50.     FramePtr dstFrameP, 
  51.     Point srcPoint, 
  52.     Point dstPoint, 
  53.     Byte color)
  54. {
  55.     Boolean        thereIsALine = true;
  56.     
  57.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  58.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  59.     START_32_BIT_MODE
  60.     
  61.         // Check to see if the line is straight horizontally or vertically
  62.     if (srcPoint.v == dstPoint.v || srcPoint.h == dstPoint.h)
  63.     {
  64.         BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
  65.     }
  66.     else
  67.     {
  68.             // Clip the line with the frameRect
  69.         thereIsALine = SWClipLineWithRect(&srcPoint, &dstPoint, &dstFrameP->frameRect);
  70.         
  71.         if (thereIsALine)
  72.             BlitLine(dstFrameP, srcPoint, dstPoint, color);
  73.     }
  74.     
  75.     END_32_BIT_MODE
  76. }
  77.  
  78.  
  79. ///--------------------------------------------------------------------------------------
  80. //  SWCopyLine
  81. ///--------------------------------------------------------------------------------------
  82.  
  83. SW_FUNC void SWCopyLine(
  84.     FramePtr srcFrameP, 
  85.     FramePtr dstFrameP, 
  86.     Point srcPoint, 
  87.     Point dstPoint)
  88. {
  89.     Boolean        thereIsALine = true;
  90.     
  91.     SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
  92.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  93.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  94.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  95.     START_32_BIT_MODE
  96.     
  97.         // Check to see if the line is straight horizontally or vertically
  98.     if (srcPoint.v == dstPoint.v || srcPoint.h == dstPoint.h)
  99.     {
  100.         BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  101.     }
  102.     else
  103.     {
  104.             // Clip the line with the dstFrameP->frameRect
  105.         thereIsALine = SWClipLineWithRect(&srcPoint, &dstPoint, &dstFrameP->frameRect);
  106.         
  107.         if (thereIsALine)
  108.             BPCopyLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  109.     }
  110.     
  111.     END_32_BIT_MODE
  112. }
  113.  
  114.  
  115. ///--------------------------------------------------------------------------------------
  116. //  SWDrawFrameRect
  117. ///--------------------------------------------------------------------------------------
  118.  
  119. SW_FUNC void SWDrawFrameRect(
  120.     FramePtr dstFrameP, 
  121.     Rect *dstRectP, 
  122.     Byte color)
  123. {
  124.     Point    srcPoint, dstPoint;
  125.     Rect    destRect = *dstRectP;
  126.     
  127.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  128.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  129.     START_32_BIT_MODE
  130.     
  131.         // Swap things around if they're in the wrong order
  132.     if (destRect.right < destRect.left)
  133.     {
  134.         destRect.right = destRect.left;
  135.         destRect.left = dstRectP->right;
  136.     }
  137.     
  138.     if (destRect.bottom < destRect.top)
  139.     {
  140.         destRect.bottom = destRect.top;
  141.         destRect.top = dstRectP->bottom;
  142.     }
  143.     
  144.         // Clip destRect with dstFrameP->frameRect
  145.     if (destRect.top < dstFrameP->frameRect.top)
  146.         destRect.top = dstFrameP->frameRect.top;
  147.     if (destRect.bottom > dstFrameP->frameRect.bottom)
  148.         destRect.bottom = dstFrameP->frameRect.bottom;
  149.     if (destRect.left < dstFrameP->frameRect.left)
  150.         destRect.left = dstFrameP->frameRect.left;
  151.     if (destRect.right > dstFrameP->frameRect.right)
  152.         destRect.right = dstFrameP->frameRect.right;
  153.     
  154.     if (destRect.right <= destRect.left || destRect.bottom <= destRect.top)
  155.         return;
  156.     
  157.     
  158.         // Draw top side
  159.     srcPoint.h = destRect.left;
  160.     srcPoint.v = destRect.top;
  161.     dstPoint.h = destRect.right-1;
  162.     dstPoint.v = destRect.top;
  163.     BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
  164.     
  165.         // Draw right side
  166.     srcPoint.h = destRect.right-1;
  167.     dstPoint.v = destRect.bottom-1;
  168.     BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
  169.     
  170.         // Draw bottom side
  171.     srcPoint.h = destRect.left;
  172.     srcPoint.v = destRect.bottom-1;
  173.     BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
  174.     
  175.         // Draw left side
  176.     srcPoint.v = destRect.top;
  177.     dstPoint.h = destRect.left;
  178.     BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
  179.     
  180.     END_32_BIT_MODE
  181. }
  182.  
  183.  
  184. ///--------------------------------------------------------------------------------------
  185. //  SWCopyFrameRect
  186. ///--------------------------------------------------------------------------------------
  187.  
  188. SW_FUNC void SWCopyFrameRect(
  189.     FramePtr srcFrameP,
  190.     FramePtr dstFrameP, 
  191.     Rect *dstRectP)
  192. {
  193.     Point    srcPoint, dstPoint;
  194.     Rect    destRect = *dstRectP;
  195.     
  196.     SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
  197.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  198.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  199.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  200.     START_32_BIT_MODE
  201.     
  202.         // Swap things around if they're in the wrong order
  203.     if (destRect.right < destRect.left)
  204.     {
  205.         destRect.right = destRect.left;
  206.         destRect.left = dstRectP->right;
  207.     }
  208.     
  209.     if (destRect.bottom < destRect.top)
  210.     {
  211.         destRect.bottom = destRect.top;
  212.         destRect.top = dstRectP->bottom;
  213.     }
  214.     
  215.         // Clip destRect with dstFrameP->frameRect
  216.     if (destRect.top < dstFrameP->frameRect.top)
  217.         destRect.top = dstFrameP->frameRect.top;
  218.     if (destRect.bottom > dstFrameP->frameRect.bottom)
  219.         destRect.bottom = dstFrameP->frameRect.bottom;
  220.     if (destRect.left < dstFrameP->frameRect.left)
  221.         destRect.left = dstFrameP->frameRect.left;
  222.     if (destRect.right > dstFrameP->frameRect.right)
  223.         destRect.right = dstFrameP->frameRect.right;
  224.     
  225.     if (destRect.right <= destRect.left || destRect.bottom <= destRect.top)
  226.         return;
  227.     
  228.     
  229.         // Draw top side
  230.     srcPoint.h = destRect.left;
  231.     srcPoint.v = destRect.top;
  232.     dstPoint.h = destRect.right-1;
  233.     dstPoint.v = destRect.top;
  234.     BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  235.     
  236.         // Draw right side
  237.     srcPoint.h = destRect.right-1;
  238.     dstPoint.v = destRect.bottom-1;
  239.     BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  240.     
  241.         // Draw bottom side
  242.     srcPoint.h = destRect.left;
  243.     srcPoint.v = destRect.bottom-1;
  244.     BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  245.     
  246.         // Draw left side
  247.     srcPoint.v = destRect.top;
  248.     dstPoint.h = destRect.left;
  249.     BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  250.     
  251.     END_32_BIT_MODE
  252. }
  253.  
  254.  
  255. ///--------------------------------------------------------------------------------------
  256. //  SWDrawLineInScrollingWorld - clips drawing to the visScrollRect
  257. ///--------------------------------------------------------------------------------------
  258.  
  259. SW_FUNC void SWDrawLineInScrollingWorld(
  260.     SpriteWorldPtr spriteWorldP, 
  261.     FramePtr dstFrameP, 
  262.     Point srcPoint, 
  263.     Point dstPoint, 
  264.     Byte color)
  265. {
  266.     Boolean        thereIsALine;
  267.     Rect        frameRect = dstFrameP->frameRect;
  268.     
  269.     SW_ASSERT(spriteWorldP != NULL);
  270.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  271.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  272.     START_32_BIT_MODE
  273.     
  274.         // Check to see if the line is straight horizontally or vertically
  275.     if (srcPoint.v == dstPoint.v || srcPoint.h == dstPoint.h)
  276.     {
  277.         Rect    visScrollRect = spriteWorldP->visScrollRect;
  278.         
  279.             // Clip the line with the visScrollRect
  280.         if (srcPoint.v < visScrollRect.top)        srcPoint.v = visScrollRect.top;
  281.         if (dstPoint.v < visScrollRect.top)        dstPoint.v = visScrollRect.top;
  282.         if (srcPoint.v >= visScrollRect.bottom)    srcPoint.v = visScrollRect.bottom-1;
  283.         if (dstPoint.v >= visScrollRect.bottom)    dstPoint.v = visScrollRect.bottom-1;
  284.         if (srcPoint.h < visScrollRect.left)    srcPoint.h = visScrollRect.left;
  285.         if (dstPoint.h < visScrollRect.left)    dstPoint.h = visScrollRect.left;
  286.         if (srcPoint.h >= visScrollRect.right)    srcPoint.h = visScrollRect.right-1;
  287.         if (dstPoint.h >= visScrollRect.right)    dstPoint.h = visScrollRect.right-1;
  288.         
  289.             // Make the line's points local to the offscreen area
  290.         srcPoint.h -= spriteWorldP->horizScrollRectOffset;
  291.         srcPoint.v -= spriteWorldP->vertScrollRectOffset;
  292.         dstPoint.h -= spriteWorldP->horizScrollRectOffset;
  293.         dstPoint.v -= spriteWorldP->vertScrollRectOffset;
  294.         
  295.             // Determine whether to call the wrapping or non-wrapping version
  296.         if (srcPoint.h >= frameRect.left && srcPoint.h < frameRect.right && 
  297.             dstPoint.h >= frameRect.left && dstPoint.h < frameRect.right &&
  298.             srcPoint.v >= frameRect.top && srcPoint.v < frameRect.bottom &&
  299.             dstPoint.v >= frameRect.top && dstPoint.v < frameRect.bottom)
  300.         {
  301.                 // The line is contained entirely inside the dstFrameP
  302.             BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
  303.         }
  304.         else
  305.         {
  306.                 // The line needs wrapping
  307.             BlitStraightWrappingLine(dstFrameP, srcPoint, dstPoint, color);
  308.         }
  309.     }
  310.     else
  311.     {
  312.             // Clip the line with the visScrollRect
  313.         thereIsALine = SWClipLineWithRect(&srcPoint, &dstPoint, &spriteWorldP->visScrollRect);
  314.         
  315.             // Make the line's points local to the offscreen area
  316.         srcPoint.h -= spriteWorldP->horizScrollRectOffset;
  317.         srcPoint.v -= spriteWorldP->vertScrollRectOffset;
  318.         dstPoint.h -= spriteWorldP->horizScrollRectOffset;
  319.         dstPoint.v -= spriteWorldP->vertScrollRectOffset;
  320.         
  321.         if (thereIsALine)
  322.         {
  323.                 // Determine whether to call the wrapping or non-wrapping version
  324.             if (srcPoint.h >= frameRect.left && srcPoint.h < frameRect.right && 
  325.                 dstPoint.h >= frameRect.left && dstPoint.h < frameRect.right &&
  326.                 srcPoint.v >= frameRect.top && srcPoint.v < frameRect.bottom &&
  327.                 dstPoint.v >= frameRect.top && dstPoint.v < frameRect.bottom)
  328.             {
  329.                     // The line is contained entirely inside the dstFrameP
  330.                 BlitLine(dstFrameP, srcPoint, dstPoint, color);
  331.             }
  332.             else
  333.             {
  334.                     // The line needs wrapping
  335.                 BlitWrappingLine(dstFrameP, srcPoint, dstPoint, color);
  336.             }
  337.         }
  338.     }
  339.     
  340.     END_32_BIT_MODE
  341. }
  342.  
  343.  
  344. ///--------------------------------------------------------------------------------------
  345. //  SWCopyLineInScrollingWorld - clips drawing to the visScrollRect
  346. ///--------------------------------------------------------------------------------------
  347.  
  348. SW_FUNC void SWCopyLineInScrollingWorld(
  349.     SpriteWorldPtr spriteWorldP, 
  350.     FramePtr srcFrameP, 
  351.     FramePtr dstFrameP, 
  352.     Point srcPoint, 
  353.     Point dstPoint,
  354.     Rect *clipRectP)
  355. {
  356.     Boolean        thereIsALine;
  357.     Rect        frameRect = dstFrameP->frameRect;
  358.     short        vertScrollRectOffset, horizScrollRectOffset;
  359.     
  360.     SW_ASSERT(spriteWorldP != NULL);
  361.     SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
  362.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  363.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  364.     START_32_BIT_MODE
  365.     
  366.         // ClipRectP should be either the visScrollRect or oldVisScrollRect
  367.     vertScrollRectOffset = spriteWorldP->backRect.bottom * 
  368.         (clipRectP->top / spriteWorldP->backRect.bottom);
  369.  
  370.     horizScrollRectOffset = spriteWorldP->backRect.right *
  371.         (clipRectP->left / spriteWorldP->backRect.right);
  372.     
  373.         // Check to see if the line is straight horizontally or vertically
  374.     if (srcPoint.v == dstPoint.v || srcPoint.h == dstPoint.h)
  375.     {
  376.             // Clip the line with the visScrollRect
  377.         if (srcPoint.v < clipRectP->top)        srcPoint.v = clipRectP->top;
  378.         if (dstPoint.v < clipRectP->top)        dstPoint.v = clipRectP->top;
  379.         if (srcPoint.v >= clipRectP->bottom)    srcPoint.v = clipRectP->bottom-1;
  380.         if (dstPoint.v >= clipRectP->bottom)    dstPoint.v = clipRectP->bottom-1;
  381.         if (srcPoint.h < clipRectP->left)        srcPoint.h = clipRectP->left;
  382.         if (dstPoint.h < clipRectP->left)        dstPoint.h = clipRectP->left;
  383.         if (srcPoint.h >= clipRectP->right)        srcPoint.h = clipRectP->right-1;
  384.         if (dstPoint.h >= clipRectP->right)        dstPoint.h = clipRectP->right-1;
  385.         
  386.             // Make the line's points local to the offscreen area
  387.         srcPoint.h -= horizScrollRectOffset;
  388.         srcPoint.v -= vertScrollRectOffset;
  389.         dstPoint.h -= horizScrollRectOffset;
  390.         dstPoint.v -= vertScrollRectOffset;
  391.         
  392.             // Determine whether to call the wrapping or non-wrapping version
  393.         if (srcPoint.h >= frameRect.left && srcPoint.h < frameRect.right && 
  394.             dstPoint.h >= frameRect.left && dstPoint.h < frameRect.right &&
  395.             srcPoint.v >= frameRect.top && srcPoint.v < frameRect.bottom &&
  396.             dstPoint.v >= frameRect.top && dstPoint.v < frameRect.bottom)
  397.         {
  398.                 // The line is contained entirely inside the dstFrameP
  399.             BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  400.         }
  401.         else
  402.         {
  403.                 // The line needs wrapping
  404.             BPCopyStraightWrappingLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  405.         }
  406.     }
  407.     else
  408.     {
  409.             // Clip the line with clipRectP (visScrollRect or oldVisScrollRect)
  410.         thereIsALine = SWClipLineWithRect(&srcPoint, &dstPoint, clipRectP);
  411.         
  412.             // Make the line's points local to the offscreen area
  413.         srcPoint.h -= horizScrollRectOffset;
  414.         srcPoint.v -= vertScrollRectOffset;
  415.         dstPoint.h -= horizScrollRectOffset;
  416.         dstPoint.v -= vertScrollRectOffset;
  417.         
  418.         if (thereIsALine)
  419.         {
  420.                 // Determine whether to call the wrapping or non-wrapping version
  421.             if (srcPoint.h >= frameRect.left && srcPoint.h < frameRect.right && 
  422.                 dstPoint.h >= frameRect.left && dstPoint.h < frameRect.right &&
  423.                 srcPoint.v >= frameRect.top && srcPoint.v < frameRect.bottom &&
  424.                 dstPoint.v >= frameRect.top && dstPoint.v < frameRect.bottom)
  425.             {
  426.                     // The line is contained entirely inside the frameRect
  427.                 BPCopyLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  428.             }
  429.             else
  430.             {
  431.                     // The line needs wrapping
  432.                 BPCopyWrappingLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
  433.             }
  434.         }
  435.     }
  436.     
  437.     END_32_BIT_MODE
  438. }
  439.  
  440.  
  441. ///--------------------------------------------------------------------------------------
  442. //  SWDrawFrameRectInScrollingWorld
  443. //    The dstFrameP should be either the work area or the background area.
  444. ///--------------------------------------------------------------------------------------
  445.  
  446. SW_FUNC void SWDrawFrameRectInScrollingWorld(
  447.     SpriteWorldPtr spriteWorldP, 
  448.     FramePtr dstFrameP, 
  449.     Rect *dstRectP, 
  450.     Byte color)
  451. {
  452.     Point            srcPoint, dstPoint;
  453.     Rect            destRect = *dstRectP;
  454.     Rect            frameRect = dstFrameP->frameRect;
  455.     Boolean            leftClipped, topClipped, rightClipped, bottomClipped;
  456.     BlitLineProcPtr    lineProcPtr;
  457.     
  458.     SW_ASSERT(spriteWorldP != NULL);
  459.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  460.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  461.     START_32_BIT_MODE
  462.     
  463.     leftClipped = topClipped = rightClipped = bottomClipped = false;
  464.     
  465.         // Clip destRect with spriteWorldP->visScrollRect
  466.     if (destRect.top < spriteWorldP->visScrollRect.top)
  467.     {
  468.         destRect.top = spriteWorldP->visScrollRect.top;
  469.         topClipped = true;
  470.     }
  471.     if (destRect.bottom > spriteWorldP->visScrollRect.bottom)
  472.     {
  473.         destRect.bottom = spriteWorldP->visScrollRect.bottom;
  474.         bottomClipped = true;
  475.     }
  476.     if (destRect.left < spriteWorldP->visScrollRect.left)
  477.     {
  478.         destRect.left = spriteWorldP->visScrollRect.left;
  479.         leftClipped = true;
  480.     }
  481.     if (destRect.right > spriteWorldP->visScrollRect.right)
  482.     {
  483.         destRect.right = spriteWorldP->visScrollRect.right;
  484.         rightClipped = true;
  485.     }
  486.         
  487.     if (destRect.right <= destRect.left || destRect.bottom <= destRect.top)
  488.         return;
  489.     
  490.     
  491.         // Make the line's points local to the offscreen area
  492.     destRect.left -= spriteWorldP->horizScrollRectOffset;
  493.     destRect.right -= spriteWorldP->horizScrollRectOffset;
  494.     destRect.top -= spriteWorldP->vertScrollRectOffset;
  495.     destRect.bottom -= spriteWorldP->vertScrollRectOffset;
  496.     
  497.         // Determine whether to call the wrapping or non-wrapping version
  498.     if (destRect.left >= frameRect.left && destRect.left < frameRect.right && 
  499.         destRect.right >= frameRect.left && destRect.right < frameRect.right &&
  500.         destRect.top >= frameRect.top && destRect.top < frameRect.bottom &&
  501.         destRect.bottom >= frameRect.top && destRect.bottom < frameRect.bottom)
  502.     {
  503.         lineProcPtr = BlitLine;     // The line is contained entirely inside the frameRect
  504.     }
  505.     else
  506.     {
  507.         lineProcPtr = BlitWrappingLine;    // The line needs wrapping
  508.     }
  509.     
  510.     
  511.         // Draw top side
  512.     srcPoint.h = destRect.left;
  513.     srcPoint.v = destRect.top;
  514.     dstPoint.h = destRect.right-1;
  515.     dstPoint.v = destRect.top;
  516.     if (!topClipped)
  517.         (*lineProcPtr)(dstFrameP, srcPoint, dstPoint, color);
  518.     
  519.         // Draw right side
  520.     srcPoint.h = destRect.right-1;
  521.     dstPoint.v = destRect.bottom-1;
  522.     if (!rightClipped)
  523.         (*lineProcPtr)(dstFrameP, srcPoint, dstPoint, color);
  524.     
  525.         // Draw bottom side
  526.     srcPoint.h = destRect.left;
  527.     srcPoint.v = destRect.bottom-1;
  528.     if (!bottomClipped)
  529.         (*lineProcPtr)(dstFrameP, srcPoint, dstPoint, color);
  530.     
  531.         // Draw left side
  532.     srcPoint.v = destRect.top;
  533.     dstPoint.h = destRect.left;
  534.     if (!leftClipped)
  535.         (*lineProcPtr)(dstFrameP, srcPoint, dstPoint, color);
  536.  
  537.     END_32_BIT_MODE
  538. }
  539.  
  540.  
  541. ///--------------------------------------------------------------------------------------
  542. //  SWCopyFrameRectInScrollingWorld
  543. //  The dstFrameP should be either the work area or the background area.
  544. ///--------------------------------------------------------------------------------------
  545.  
  546. SW_FUNC void SWCopyFrameRectInScrollingWorld(
  547.     SpriteWorldPtr spriteWorldP, 
  548.     FramePtr srcFrameP, 
  549.     FramePtr dstFrameP, 
  550.     Rect *dstRectP,
  551.     Rect *clipRectP)
  552. {
  553.     Point            srcPoint, dstPoint;
  554.     Rect            destRect = *dstRectP;
  555.     Rect            frameRect = dstFrameP->frameRect;
  556.     Boolean            leftClipped, topClipped, rightClipped, bottomClipped;
  557.     short            horizScrollRectOffset, vertScrollRectOffset;
  558.     CopyLineProcPtr    lineProcPtr;
  559.     
  560.     SW_ASSERT(spriteWorldP != NULL);
  561.     SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
  562.     SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
  563.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  564.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  565.     START_32_BIT_MODE
  566.     
  567.         // ClipRectP should be either the visScrollRect or oldVisScrollRect
  568.     vertScrollRectOffset = spriteWorldP->backRect.bottom * 
  569.         (clipRectP->top / spriteWorldP->backRect.bottom);
  570.  
  571.     horizScrollRectOffset = spriteWorldP->backRect.right *
  572.         (clipRectP->left / spriteWorldP->backRect.right);
  573.     
  574.     leftClipped = topClipped = rightClipped = bottomClipped = false;
  575.     
  576.         // Clip destRect with spriteWorldP->visScrollRect
  577.     if (destRect.top < clipRectP->top)
  578.     {
  579.         destRect.top = clipRectP->top;
  580.         topClipped = true;
  581.     }
  582.     if (destRect.bottom > clipRectP->bottom)
  583.     {
  584.         destRect.bottom = clipRectP->bottom;
  585.         bottomClipped = true;
  586.     }
  587.     if (destRect.left < clipRectP->left)
  588.     {
  589.         destRect.left = clipRectP->left;
  590.         leftClipped = true;
  591.     }
  592.     if (destRect.right > clipRectP->right)
  593.     {
  594.         destRect.right = clipRectP->right;
  595.         rightClipped = true;
  596.     }
  597.         
  598.     if (destRect.right <= destRect.left || destRect.bottom <= destRect.top)
  599.         return;
  600.     
  601.         // Make the line's points local to the offscreen area
  602.     destRect.left -= horizScrollRectOffset;
  603.     destRect.right -= horizScrollRectOffset;
  604.     destRect.top -= vertScrollRectOffset;
  605.     destRect.bottom -= vertScrollRectOffset;
  606.     
  607.         // Determine whether to call the wrapping or non-wrapping version
  608.     if (destRect.left >= frameRect.left && destRect.left < frameRect.right && 
  609.         destRect.right >= frameRect.left && destRect.right < frameRect.right &&
  610.         destRect.top >= frameRect.top && destRect.top < frameRect.bottom &&
  611.         destRect.bottom >= frameRect.top && destRect.bottom < frameRect.bottom)
  612.     {
  613.         lineProcPtr = BPCopyStraightLine; // The line is contained entirely inside the frameRect
  614.     }
  615.     else
  616.     {
  617.         lineProcPtr = BPCopyStraightWrappingLine;    // The line needs wrapping
  618.     }
  619.     
  620.     
  621.         // Draw top side
  622.     srcPoint.h = destRect.left;
  623.     srcPoint.v = destRect.top;
  624.     dstPoint.h = destRect.right-1;
  625.     dstPoint.v = destRect.top;
  626.     if (!topClipped)        // Draw top if it wasn't clipped
  627.         (*lineProcPtr)(srcFrameP, dstFrameP, srcPoint, dstPoint);
  628.     
  629.         // Draw right side
  630.     srcPoint.h = destRect.right-1;
  631.     dstPoint.v = destRect.bottom-1;
  632.     if (!rightClipped)    // Draw right if it wasn't clipped
  633.         (*lineProcPtr)(srcFrameP, dstFrameP, srcPoint, dstPoint);
  634.     
  635.         // Draw bottom side
  636.     srcPoint.h = destRect.left;
  637.     srcPoint.v = destRect.bottom-1;
  638.     if (!bottomClipped)    // Draw bottom if it wasn't clipped
  639.         (*lineProcPtr)(srcFrameP, dstFrameP, srcPoint, dstPoint);
  640.     
  641.         // Draw left side
  642.     srcPoint.v = destRect.top;
  643.     dstPoint.h = destRect.left;
  644.     if (!leftClipped)        // Draw left if it wasn't clipped
  645.         (*lineProcPtr)(srcFrameP, dstFrameP, srcPoint, dstPoint);
  646.     
  647.     END_32_BIT_MODE
  648. }
  649.  
  650.  
  651. #pragma mark -
  652. #pragma mark *** Diagonal Line Blitters:
  653. ///--------------------------------------------------------------------------------------
  654. //  SWClipLineWithRect    - Note: lines clipped with this routine will always be slightly
  655. //    different than the unclipped version, since the accum and dx or dy from this routine
  656. //    are not passed to the actual line drawing function.
  657. ///--------------------------------------------------------------------------------------
  658.  
  659. SW_FUNC Boolean SWClipLineWithRect(
  660.     Point *srcPoint, 
  661.     Point *dstPoint, 
  662.     Rect *clipRectP)
  663. {
  664.     short        x1 = srcPoint->h, y1 = srcPoint->v, 
  665.                 x2 = dstPoint->h, y2 = dstPoint->v;
  666.     short        dx, dy, sx, sy, accum;
  667.     short        lastX, lastY;
  668.     Boolean        x1IsInRect, y1IsInRect, x2IsInRect, y2IsInRect;
  669.     Boolean        foundStartPt, endPointIsInRect;
  670.     Rect        clipRect = *clipRectP;
  671.     
  672. //    InsetRect(&clipRect, 50, 50);    // Useful for testing
  673.     
  674.     x1IsInRect = (x1 >= clipRect.left && x1 < clipRect.right);
  675.     y1IsInRect = (y1 >= clipRect.top && y1 < clipRect.bottom);
  676.     x2IsInRect = (x2 >= clipRect.left && x2 < clipRect.right);
  677.     y2IsInRect = (y2 >= clipRect.top && y2 < clipRect.bottom);
  678.     
  679.         // If line needs no clipping, return
  680.     if (x1IsInRect && y1IsInRect && x2IsInRect && y2IsInRect)
  681.     {
  682.         return true;
  683.     }
  684.     
  685.     
  686.     dx = x2 - x1;
  687.     dy = y2 - y1;
  688.  
  689.     sx = SIGN(dx);
  690.     sy = SIGN(dy);
  691.     
  692.     dx = ABS(dx);
  693.     dy = ABS(dy);
  694.     
  695.     foundStartPt = false;
  696.     endPointIsInRect = false;
  697.     
  698.         // The possibilities are: A) Both start and end points are outside the rect.
  699.         // B) Only the start point is outside. C) Only the end point is outside.
  700.         // We know that at least one point is outside, since otherwise this function
  701.         // would have returned already.
  702.     
  703.         // Check first pixel in line
  704.     if (x1IsInRect && y1IsInRect)
  705.     {
  706.         foundStartPt = true;
  707.         lastX = x1;            // Store last point in line as well, in case only
  708.         lastY = y1;            // one pixel is inside the clipRect.
  709.     }
  710.     
  711.     if (x2IsInRect && y2IsInRect)
  712.     {
  713.         endPointIsInRect = true;
  714.     }
  715.     
  716.     
  717.     if (dx > dy)    // Longer horizontally than vertically
  718.     {
  719.         accum = dx >> 1;    // accum = dx/2;
  720.         while (x1 != x2)
  721.         {
  722.             accum -= dy;
  723.             if (accum < 0)
  724.             {
  725.                 accum += dx;
  726.                 y1 += sy;
  727.                 y1IsInRect = (y1 >= clipRect.top && y1 < clipRect.bottom);
  728.             }
  729.             x1 += sx;
  730.             x1IsInRect = (x1 >= clipRect.left && x1 < clipRect.right);
  731.             
  732.             if (x1IsInRect && y1IsInRect)    // Determine if current point is in rect
  733.             {
  734.                 if (foundStartPt == false)
  735.                 {
  736.                     srcPoint->h = x1;    // Store first point in line
  737.                     srcPoint->v = y1;
  738.                     foundStartPt = true;
  739.                     
  740.                     if (endPointIsInRect)
  741.                         return true; // Leave early, since we only needed to clip the first half
  742.                 }
  743.  
  744.                 lastX = x1;    // Store last point in line
  745.                 lastY = y1;    // (We keep doing this until we hit the end.)
  746.             }
  747.             else if (foundStartPt == true)
  748.             {
  749.                 break;    // the line is leaving clipRect, so break early to save time
  750.             }
  751.         }
  752.     } 
  753.     else     // Longer vertically than horizontally, or both equal in length
  754.     {
  755.         accum = dy >> 1;    // accum = dy/2;
  756.         while (y1 != y2)
  757.         {
  758.             accum -= dx;
  759.             if (accum < 0)
  760.             {
  761.                 accum += dy;
  762.                 x1 += sx;
  763.                 x1IsInRect = (x1 >= clipRect.left && x1 < clipRect.right);
  764.             }
  765.             y1 += sy;
  766.             y1IsInRect = (y1 >= clipRect.top && y1 < clipRect.bottom);
  767.             
  768.             if (x1IsInRect && y1IsInRect)    // Determine if current point is in rect
  769.             {
  770.                 if (foundStartPt == false)
  771.                 {
  772.                     srcPoint->h = x1;    // Store first point in line
  773.                     srcPoint->v = y1;
  774.                     foundStartPt = true;
  775.                     
  776.                     if (endPointIsInRect)
  777.                         return true; // Leave early, since we only needed to clip the first half
  778.                 }
  779.  
  780.                 lastX = x1;    // Store last point in line
  781.                 lastY = y1;    // (We keep doing this until we hit the end.)
  782.             }
  783.             else if (foundStartPt == true)
  784.             {
  785.                 break;    // the line is leaving clipRect, so break early to save time
  786.             }
  787.         }
  788.     }
  789.     
  790.         // Store last point in line
  791.     dstPoint->h = lastX;    // lastX is the pixel just before we ran into the pixel outside bounds
  792.     dstPoint->v = lastY;    
  793.     
  794.         // Tell caller if we ever found any point of the line inside clipRect
  795.     return foundStartPt;
  796. }
  797.  
  798.  
  799. #if !SW_PPC
  800. #ifndef MPW_C
  801. ///--------------------------------------------------------------------------------------
  802. //    BlitLine68kAsm - called by SWDrawLine68kAsm. Written by Oleg Doperchuk.
  803. ///--------------------------------------------------------------------------------------
  804.  
  805. SW_ASM_FUNC void BlitLine68kAsm
  806.     (Ptr baseAddr, 
  807.     unsigned long rowBytes, 
  808.     short x1, 
  809.     short x2, 
  810.     short y1, 
  811.     short y2, 
  812.     Byte color)
  813. {
  814.     SW_ASM_BEGIN
  815.  
  816. #if __MWERKS__
  817.         fralloc +
  818. #endif
  819.  
  820.         //dc.w 0xA9FF
  821.         movem.l d0-d7/a0-a6,-(a7)
  822.         moveq #0,d0
  823.         moveq #0,d1
  824.         moveq #0,d2
  825.         moveq #0,d3
  826.         move.w x1,d0
  827.         move.w y1,d1
  828.         move.w x2,d2
  829.         move.w y2,d3
  830.         sub.w d0,d2            // d2 = !x = ( x2 - x1 )
  831.         bpl.s @noswap
  832.         exg d1,d3            // swap endpoints
  833.         neg.w d2            // !x = -!x = ( x1 - x2 )
  834.         sub.w d2,d0            // d0 =  x1 - ( x1 - x2 ) = x2
  835. @noswap:
  836.         sub.w d1,d3            // d3 = !y = ( y2 - y1 )
  837.         move.l baseAddr,a0
  838.         move.l rowBytes,d6    
  839.         mulu.l d6,d1        
  840.         add.l d1,d0            
  841.         add.l d0,a0            // a0 = address of the first point to draw
  842.         move.b color,d7
  843. // now we can freely use d0/d1 
  844.         tst.w d3            // Line upward?
  845.         bmi @LineUp            // yes
  846.         beq @Horiz            // horizontal line
  847.         tst.w d2            // !x = 0 - vertical line downward
  848.         beq @VertDn
  849.         cmp.w d2,d3            // test line slope
  850.         beq @DiagDn            // slope = 1
  851.         bpl @SteepDn        // slope > 1
  852.  
  853.         moveq #0,d0            // lower 32bits    
  854.         divu.l d2,d3:d0        // d0 = 32bit ( !y/!x )        
  855.         moveq #0,d1            // accumulated error
  856. @FDLoop:
  857.         move.b d7,(a0)+        // Plot a point and move 1 pixel rightward
  858.         add.l d0,d1            // Add an accumulated error
  859.         bcs.s @FDCarry
  860.         dbra d2,@FDLoop        
  861.         bra @exit    
  862. @FDCarry:
  863.         add.l d6,a0            // One line down
  864.         dbra d2,@FDLoop
  865.         bra @exit    
  866. @DiagDn:
  867.         addq.l #1,d6        // Offset is rowbytes+1
  868. @DDLoop:
  869.         move.b d7,(a0)        // draw line
  870.         add.l d6,a0
  871.         dbra d2,@DDLoop
  872.         bra @exit
  873. @SteepDn:
  874.         moveq #0,d0
  875.         divu.l d3,d2:d0        // d0 = 32bit ( !x/!y )
  876.         moveq #0,d1            // accumulated error
  877. @SDLoop:
  878.         move.b d7,(a0)        // plot a point
  879.         add.l d6,a0            // move 1 pixel downward
  880.         add.l d0,d1            // Add an accumulated error
  881.         bcs.s @SDCarry
  882.         dbra d3,@SDLoop
  883.         bra @exit
  884. @SDCarry:
  885.         addq.l #1,a0
  886.         dbra d3,@SDLoop
  887.         bra @exit
  888. @Horiz:
  889.         move.b d7,(a0)+
  890.         dbra d2,@Horiz
  891.         bra @exit
  892. @VertDn:
  893.         move.b d7,(a0)        // offset is rowbytes
  894.         add.l d6,a0
  895.         dbra d3,@VertDn
  896.         bra @exit
  897. @LineUp:
  898.         neg.w d3    
  899.         tst.w d2
  900.         beq @VertUp        
  901.         cmp.w d2,d3
  902.         beq @DiagUp            // slope = -1
  903.         bpl @SteepUp        // slope < -1
  904.         
  905.         moveq #0,d0            // lower 32bits
  906.         divu.l d2,d3:d0        // d0 = 32bit ( !y/!x )        
  907.         moveq #0,d1            // accumulated error
  908. @FULoop:
  909.         move.b d7,(a0)+        // Plot a point and move 1 pixel rightward
  910.         add.l d0,d1            // Add an accumulated error
  911.         bcs.s @FUCarry
  912.         dbra d2,@FULoop        
  913.         bra @exit    
  914. @FUCarry:
  915.         sub.l d6,a0            // One line up
  916.         dbra d2,@FULoop
  917.         bra @exit    
  918. @DiagUp:
  919.         subq.l #1,d6        // offset is 1-rowbytes
  920. @DULoop:
  921.         move.b d7,(a0)        // draw line
  922.         sub.l d6,a0
  923.         dbra d2,@DULoop
  924.         bra @exit
  925. @SteepUp:
  926.         moveq #0,d0
  927.         divu.l d3,d2:d0        // d0 = 32bit ( !x/!y )
  928.         moveq #0,d1            // accumulated error
  929. @SULoop:
  930.         move.b d7,(a0)        // plot a point
  931.         sub.l d6,a0            // move 1 pixel upward
  932.         add.l d0,d1            // Add an accumulated error
  933.         bcs.s @SUCarry
  934.         dbra d3,@SULoop
  935.         bra @exit
  936. @SUCarry:
  937.         addq.l #1,a0
  938.         dbra d3,@SULoop
  939.         bra @exit
  940. @VertUp:
  941.         move.b d7,(a0)        // offset is -rowbytes
  942.         sub.l d6,a0
  943.         dbra d3,@VertUp
  944. @exit:    movem.l (a7)+,d0-d7/a0-a6
  945.     
  946. #if __MWERKS__
  947.         frfree
  948. #endif
  949.  
  950.     SW_ASM_END    
  951. }
  952. #endif
  953. #endif
  954.  
  955. ///--------------------------------------------------------------------------------------
  956. //  BlitLine - line-drawing code in C. Clipping must be done before this is called.
  957. ///--------------------------------------------------------------------------------------
  958.  
  959. SW_FUNC void BlitLine(
  960.     FramePtr dstFrameP, 
  961.     Point srcPoint, 
  962.     Point dstPoint, 
  963.     Byte color)
  964. {
  965.     register Ptr    baseAddr = dstFrameP->frameBaseAddr;
  966.     unsigned long    rowBytes = dstFrameP->frameRowBytes;
  967.     short            x1 = srcPoint.h, y1 = srcPoint.v, 
  968.                     x2 = dstPoint.h, y2 = dstPoint.v;
  969.     short            dx, dy, sx, sy, iy;
  970.     short            accum;
  971.     
  972.     dx = x2 - x1;
  973.     dy = y2 - y1;
  974.  
  975.     sx = SIGN(dx);
  976.     sy = SIGN(dy);
  977.     
  978.     dx = ABS(dx);
  979.     dy = ABS(dy);
  980.     
  981.     iy = (sy < 0) ? -rowBytes : rowBytes;
  982.     
  983.     baseAddr += dstFrameP->scanLinePtrArray[y1] + x1;
  984.     *baseAddr = color;    // Draw the first pixel
  985.     
  986.     if(dx > dy)        // Longer horizontally than vertically
  987.     {
  988.         accum = dx >> 1;
  989.         while(x1 != x2)
  990.         {
  991.             accum -= dy;
  992.             if(accum < 0)
  993.             {
  994.                 accum += dx;
  995.                 baseAddr += iy;
  996.             }
  997.             x1 += sx;
  998.             baseAddr += sx;
  999.             *baseAddr = color;
  1000.         }
  1001.     } 
  1002.     else     // Longer vertically than horizontally, or both equal in length
  1003.     {
  1004.         accum = dy >> 1;
  1005.         while(y1 != y2)
  1006.         {
  1007.             accum -= dx;
  1008.             if(accum < 0)
  1009.             {
  1010.                 accum += dy;
  1011.                 baseAddr += sx;
  1012.             }
  1013.             y1 += sy;
  1014.             baseAddr += iy;
  1015.             *baseAddr = color;
  1016.         }
  1017.     }
  1018. }
  1019.  
  1020.  
  1021. ///--------------------------------------------------------------------------------------
  1022. //  BPCopyLine - line-drawing code in C. Clipping must be done before this is called.
  1023. ///--------------------------------------------------------------------------------------
  1024.  
  1025. SW_FUNC void BPCopyLine(
  1026.     FramePtr srcFrameP, 
  1027.     FramePtr dstFrameP, 
  1028.     Point srcPoint, 
  1029.     Point dstPoint)
  1030. {
  1031.     Ptr                srcBaseAddr = srcFrameP->frameBaseAddr;
  1032.     Ptr                dstBaseAddr = dstFrameP->frameBaseAddr;
  1033.     unsigned long    srcRowBytes = srcFrameP->frameRowBytes;
  1034.     unsigned long    dstRowBytes = dstFrameP->frameRowBytes;
  1035.     short            x1 = srcPoint.h, y1 = srcPoint.v, 
  1036.                     x2 = dstPoint.h, y2 = dstPoint.v;
  1037.     short            dx, dy, sx, sy, srciy, dstiy;
  1038.     short            accum;
  1039.     
  1040.     dx = x2 - x1;
  1041.     dy = y2 - y1;
  1042.  
  1043.     sx = SIGN(dx);
  1044.     sy = SIGN(dy);
  1045.     
  1046.     dx = ABS(dx);
  1047.     dy = ABS(dy);
  1048.     
  1049.     srcBaseAddr += srcFrameP->scanLinePtrArray[y1] + x1;
  1050.     dstBaseAddr += dstFrameP->scanLinePtrArray[y1] + x1;
  1051.     
  1052.         // Copy the first pixel in the line
  1053.     *dstBaseAddr = *srcBaseAddr;
  1054.     
  1055.     srciy = (sy < 0) ? -srcRowBytes : srcRowBytes;
  1056.     dstiy = (sy < 0) ? -dstRowBytes : dstRowBytes;
  1057.     
  1058.     
  1059.     if (dx > dy)        // Longer horizontally than vertically
  1060.     {
  1061.         accum = dx >> 1;
  1062.         while(x1 != x2)
  1063.         {
  1064.             accum -= dy;
  1065.             if(accum < 0)
  1066.             {
  1067.                 accum += dx;
  1068.                 srcBaseAddr += srciy;
  1069.                 dstBaseAddr += dstiy;
  1070.             }
  1071.             x1 += sx;
  1072.             srcBaseAddr += sx;
  1073.             dstBaseAddr += sx;
  1074.             *dstBaseAddr = *srcBaseAddr;
  1075.         }
  1076.     } 
  1077.     else     // Longer vertically than horizontally, or both equal in length
  1078.     {
  1079.         accum = dy >> 1;
  1080.         while(y1 != y2)
  1081.         {
  1082.             accum -= dx;
  1083.             if(accum < 0)
  1084.             {
  1085.                 accum += dy;
  1086.                 srcBaseAddr += sx;
  1087.                 dstBaseAddr += sx;
  1088.             }
  1089.             y1 += sy;
  1090.             srcBaseAddr += srciy;
  1091.             dstBaseAddr += dstiy;
  1092.             *dstBaseAddr = *srcBaseAddr;
  1093.         }
  1094.     }
  1095. }
  1096.  
  1097.  
  1098. ///--------------------------------------------------------------------------------------
  1099. //  BlitWrappingLine
  1100. ///--------------------------------------------------------------------------------------
  1101.  
  1102. SW_FUNC void BlitWrappingLine(
  1103.     FramePtr dstFrameP, 
  1104.     Point srcPoint, 
  1105.     Point dstPoint, 
  1106.     Byte color)
  1107. {
  1108.     Ptr                baseAddr;
  1109.     unsigned long    rowBytes = dstFrameP->frameRowBytes;
  1110.     unsigned long    vertOffset;
  1111.     short            x1 = srcPoint.h, y1 = srcPoint.v, 
  1112.                     x2 = dstPoint.h, y2 = dstPoint.v;
  1113.     short            dx, dy, sx, sy, iy;
  1114.     short            accum;
  1115.     Rect            frameRect = dstFrameP->frameRect;
  1116.     short            frameWidth, frameHeight;
  1117.     
  1118.     frameWidth = SW_RECT_WIDTH(frameRect);
  1119.     frameHeight = SW_RECT_HEIGHT(frameRect);
  1120.     
  1121.         // vertOffset = rowBytes * frameHeight;
  1122.     vertOffset = dstFrameP->scanLinePtrArray[dstFrameP->numScanLines-1] + rowBytes -
  1123.                  dstFrameP->scanLinePtrArray[0];
  1124.     
  1125.     dx = x2 - x1;
  1126.     dy = y2 - y1;
  1127.  
  1128.     sx = SIGN(dx);
  1129.     sy = SIGN(dy);
  1130.     
  1131.     dx = ABS(dx);
  1132.     dy = ABS(dy);
  1133.     
  1134.         // Even the very first pixel we draw might need to be wrapped before we draw it.
  1135.     if (y1 >= frameRect.bottom)
  1136.     {
  1137.         y1 -= frameHeight;
  1138.         y2 -= frameHeight;
  1139.     }
  1140.     else if (y1 < frameRect.top)
  1141.     {
  1142.         y1 += frameHeight;
  1143.         y2 += frameHeight;
  1144.     }
  1145.     
  1146.     if (x1 >= frameRect.right)
  1147.     {
  1148.         x1 -= frameWidth;
  1149.         x2 -= frameWidth;
  1150.     }
  1151.     else if (x1 < frameRect.left)
  1152.     {
  1153.         x1 += frameWidth;
  1154.         x2 += frameWidth;
  1155.     }
  1156.     
  1157.     baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
  1158.     *baseAddr = color;
  1159.     
  1160.     iy = (sy < 0) ? -rowBytes : rowBytes;
  1161.     
  1162.     if (dx > dy)        // Longer horizontally than vertically
  1163.     {
  1164.         accum = dx >> 1;    // accum = dx/2;
  1165.         while (x1 != x2)
  1166.         {
  1167.             accum -= dy;
  1168.             if (accum < 0)
  1169.             {
  1170.                 accum += dx;
  1171.                 y1 += sy;
  1172.                 baseAddr += iy;        // Move pixel up/down one row
  1173.                 
  1174.                 if (y1 >= frameRect.bottom)
  1175.                 {
  1176.                     y1 -= frameHeight;
  1177.                     y2 -= frameHeight;
  1178.                     baseAddr -= vertOffset;        // Jump to top side
  1179.                 }
  1180.                 else if (y1 < frameRect.top)
  1181.                 {
  1182.                     y1 += frameHeight;
  1183.                     y2 += frameHeight;
  1184.                     baseAddr += vertOffset;        // Jump to bottom side
  1185.                 }
  1186.             }
  1187.             x1 += sx;
  1188.             baseAddr += sx;                // Move left/right one pixel
  1189.             
  1190.             if (x1 >= frameRect.right)
  1191.             {
  1192.                 x1 -= frameWidth;
  1193.                 x2 -= frameWidth;
  1194.                 baseAddr -= frameWidth;    // Jump to left side
  1195.             }
  1196.             else if (x1 < frameRect.left)
  1197.             {
  1198.                 x1 += frameWidth;
  1199.                 x2 += frameWidth;
  1200.                 baseAddr += frameWidth;    // Jump to right side
  1201.             }
  1202.             
  1203.             *baseAddr = color;
  1204.         }
  1205.     } 
  1206.     else     // Longer vertically than horizontally, or both equal in length
  1207.     {
  1208.         accum = dy >> 1;    // accum = dy/2;
  1209.         while (y1 != y2)
  1210.         {
  1211.             accum -= dx;
  1212.             if (accum < 0)
  1213.             {
  1214.                 accum += dy;
  1215.                 x1 += sx;
  1216.                 baseAddr += sx;
  1217.                 
  1218.                 if (x1 >= frameRect.right)
  1219.                 {
  1220.                     x1 -= frameWidth;
  1221.                     x2 -= frameWidth;
  1222.                     baseAddr -= frameWidth;    // Jump to left side
  1223.                 }
  1224.                 else if (x1 < frameRect.left)
  1225.                 {
  1226.                     x1 += frameWidth;
  1227.                     x2 += frameWidth;
  1228.                     baseAddr += frameWidth;    // Jump to right side
  1229.                 }
  1230.             }
  1231.             y1 += sy;
  1232.             baseAddr += iy;
  1233.             
  1234.             if (y1 >= frameRect.bottom)
  1235.             {
  1236.                 y1 -= frameHeight;
  1237.                 y2 -= frameHeight;
  1238.                 baseAddr -= vertOffset;        // Jump to top side
  1239.             }
  1240.             else if (y1 < frameRect.top)
  1241.             {
  1242.                 y1 += frameHeight;
  1243.                 y2 += frameHeight;
  1244.                 baseAddr += vertOffset;        // Jump to bottom side
  1245.             }
  1246.             
  1247.             *baseAddr = color;
  1248.         }
  1249.     }
  1250. }
  1251.  
  1252.  
  1253. ///--------------------------------------------------------------------------------------
  1254. //  BPCopyWrappingLine - assumes srcFrameP and dstFrameP are the same size!
  1255. ///--------------------------------------------------------------------------------------
  1256.  
  1257. SW_FUNC void BPCopyWrappingLine(
  1258.     FramePtr srcFrameP, 
  1259.     FramePtr dstFrameP, 
  1260.     Point srcPoint, 
  1261.     Point dstPoint)
  1262. {
  1263.     Ptr                srcBaseAddr = srcFrameP->frameBaseAddr;
  1264.     Ptr                dstBaseAddr = dstFrameP->frameBaseAddr;
  1265.     unsigned long    srcRowBytes = srcFrameP->frameRowBytes;
  1266.     unsigned long    dstRowBytes = dstFrameP->frameRowBytes;
  1267.     unsigned long    srcVertOffset, dstVertOffset;
  1268.     short            x1 = srcPoint.h, y1 = srcPoint.v, 
  1269.                     x2 = dstPoint.h, y2 = dstPoint.v;
  1270.     short            dx, dy, sx, sy, srciy, dstiy;
  1271.     short            accum;
  1272.     Rect            frameRect = dstFrameP->frameRect;
  1273.     short            frameWidth, frameHeight;
  1274.     
  1275.     frameWidth = SW_RECT_WIDTH(frameRect);
  1276.     frameHeight = SW_RECT_HEIGHT(frameRect);
  1277.     
  1278.         // srcVertOffset = srcRowBytes * frameHeight;
  1279.     srcVertOffset = srcFrameP->scanLinePtrArray[srcFrameP->numScanLines-1] + srcRowBytes -
  1280.                     srcFrameP->scanLinePtrArray[0];
  1281.     dstVertOffset = dstFrameP->scanLinePtrArray[dstFrameP->numScanLines-1] + dstRowBytes -
  1282.                     dstFrameP->scanLinePtrArray[0];
  1283.     
  1284.     dx = x2 - x1;
  1285.     dy = y2 - y1;
  1286.  
  1287.     sx = SIGN(dx);
  1288.     sy = SIGN(dy);
  1289.     
  1290.     dx = ABS(dx);
  1291.     dy = ABS(dy);
  1292.     
  1293.         // Even the very first pixel we draw might need to be wrapped before we draw it.
  1294.     if (y1 >= frameRect.bottom)
  1295.     {
  1296.         y1 -= frameHeight;
  1297.         y2 -= frameHeight;
  1298.     }
  1299.     else if (y1 < frameRect.top)
  1300.     {
  1301.         y1 += frameHeight;
  1302.         y2 += frameHeight;
  1303.     }
  1304.     
  1305.     if (x1 >= frameRect.right)
  1306.     {
  1307.         x1 -= frameWidth;
  1308.         x2 -= frameWidth;
  1309.     }
  1310.     else if (x1 < frameRect.left)
  1311.     {
  1312.         x1 += frameWidth;
  1313.         x2 += frameWidth;
  1314.     }
  1315.     
  1316.     srcBaseAddr += srcFrameP->scanLinePtrArray[y1] + x1;
  1317.     dstBaseAddr += dstFrameP->scanLinePtrArray[y1] + x1;
  1318.     
  1319.         // Copy the first pixel in the line
  1320.     *dstBaseAddr = *srcBaseAddr;
  1321.     
  1322.     srciy = (sy < 0) ? -srcRowBytes : srcRowBytes;
  1323.     dstiy = (sy < 0) ? -dstRowBytes : dstRowBytes;
  1324.     
  1325.     if (dx > dy)        // Longer horizontally than vertically
  1326.     {
  1327.         accum = dx >> 1;    // accum = dx/2;
  1328.         while (x1 != x2)
  1329.         {
  1330.             accum -= dy;
  1331.             if (accum < 0)
  1332.             {
  1333.                 accum += dx;
  1334.                 y1 += sy;
  1335.                 srcBaseAddr += srciy;        // Move pixel up/down one row
  1336.                 dstBaseAddr += dstiy;
  1337.                 
  1338.                 if (y1 >= frameRect.bottom)
  1339.                 {
  1340.                     y1 -= frameHeight;
  1341.                     y2 -= frameHeight;
  1342.                     srcBaseAddr -= srcVertOffset;        // Jump to top side
  1343.                     dstBaseAddr -= dstVertOffset;
  1344.                 }
  1345.                 else if (y1 < frameRect.top)
  1346.                 {
  1347.                     y1 += frameHeight;
  1348.                     y2 += frameHeight;
  1349.                     srcBaseAddr += srcVertOffset;        // Jump to bottom side
  1350.                     dstBaseAddr += dstVertOffset;    
  1351.                 }
  1352.             }
  1353.             x1 += sx;
  1354.             srcBaseAddr += sx;                // Move left/right one pixel
  1355.             dstBaseAddr += sx;
  1356.             
  1357.             if (x1 >= frameRect.right)
  1358.             {
  1359.                 x1 -= frameWidth;
  1360.                 x2 -= frameWidth;
  1361.                 srcBaseAddr -= frameWidth;    // Jump to left side
  1362.                 dstBaseAddr -= frameWidth;
  1363.             }
  1364.             else if (x1 < frameRect.left)
  1365.             {
  1366.                 x1 += frameWidth;
  1367.                 x2 += frameWidth;
  1368.                 srcBaseAddr += frameWidth;    // Jump to right side
  1369.                 dstBaseAddr += frameWidth;
  1370.             }
  1371.             
  1372.             *dstBaseAddr = *srcBaseAddr;    // Copy the pixel
  1373.         }
  1374.     } 
  1375.     else     // Longer vertically than horizontally, or both equal in length
  1376.     {
  1377.         accum = dy >> 1;    // accum = dy/2;
  1378.         while (y1 != y2)
  1379.         {
  1380.             accum -= dx;
  1381.             if (accum < 0)
  1382.             {
  1383.                 accum += dy;
  1384.                 x1 += sx;
  1385.                 srcBaseAddr += sx;
  1386.                 dstBaseAddr += sx;
  1387.                 
  1388.                 if (x1 >= frameRect.right)
  1389.                 {
  1390.                     x1 -= frameWidth;
  1391.                     x2 -= frameWidth;
  1392.                     srcBaseAddr -= frameWidth;    // Jump to left side
  1393.                     dstBaseAddr -= frameWidth;
  1394.                 }
  1395.                 else if (x1 < frameRect.left)
  1396.                 {
  1397.                     x1 += frameWidth;
  1398.                     x2 += frameWidth;
  1399.                     srcBaseAddr += frameWidth;    // Jump to right side
  1400.                     dstBaseAddr += frameWidth;
  1401.                 }
  1402.             }
  1403.             y1 += sy;
  1404.             srcBaseAddr += srciy;
  1405.             dstBaseAddr += dstiy;
  1406.             
  1407.             if (y1 >= frameRect.bottom)
  1408.             {
  1409.                 y1 -= frameHeight;
  1410.                 y2 -= frameHeight;
  1411.                 srcBaseAddr -= srcVertOffset;        // Jump to top side
  1412.                 dstBaseAddr -= dstVertOffset;
  1413.             }
  1414.             else if (y1 < frameRect.top)
  1415.             {
  1416.                 y1 += frameHeight;
  1417.                 y2 += frameHeight;
  1418.                 srcBaseAddr += srcVertOffset;        // Jump to bottom side
  1419.                 dstBaseAddr += dstVertOffset;
  1420.             }
  1421.             
  1422.             *dstBaseAddr = *srcBaseAddr;    // Copy the pixel
  1423.         }
  1424.     }
  1425. }
  1426.  
  1427.  
  1428. #pragma mark -
  1429. #pragma mark ***Straight Line Blitters: 
  1430. ///--------------------------------------------------------------------------------------
  1431. //  BlitStraightLine - Clipping is performed by function, since it's easy for a straight line.
  1432. ///--------------------------------------------------------------------------------------
  1433.  
  1434. SW_FUNC void BlitStraightLine(
  1435.     FramePtr dstFrameP, 
  1436.     Point srcPoint, 
  1437.     Point dstPoint, 
  1438.     Byte color)
  1439. {
  1440.     unsigned long    rowBytes = dstFrameP->frameRowBytes;
  1441.     short            x1 = srcPoint.h, y1 = srcPoint.v, 
  1442.                     x2 = dstPoint.h, y2 = dstPoint.v;
  1443.     short            dx, dy;
  1444.  
  1445.     
  1446.     if (x1 == x2)        // Straight vertical line
  1447.     {
  1448.         register Ptr    baseAddr;
  1449.         
  1450.         if (y2 < y1)
  1451.         {
  1452.             y1 = dstPoint.v;    // Swap y1 and y2 if they're
  1453.             y2 = srcPoint.v;    // in the wrong order.
  1454.         }
  1455.         
  1456.             // Make sure some part of the line is inside the frameRect
  1457.         if (x1 < dstFrameP->frameRect.left || x1 >= dstFrameP->frameRect.right)
  1458.             return;
  1459.         
  1460.             // Clip the ends of the line
  1461.         if (y1 < dstFrameP->frameRect.top)
  1462.             y1 = dstFrameP->frameRect.top;
  1463.         if (y2 >= dstFrameP->frameRect.bottom)
  1464.             y2 = dstFrameP->frameRect.bottom-1;
  1465.         
  1466.         dy = y2 - y1 + 1;    // dy = number of pixels in line
  1467.         if (dy > 0)    // Make sure there is a line first!
  1468.         {
  1469.             baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
  1470.             *baseAddr = color;
  1471.             
  1472.             while (--dy)
  1473.             {
  1474.                 baseAddr += rowBytes;
  1475.                 *baseAddr = color;
  1476.             }
  1477.         }
  1478.     }
  1479.     else if (y1 == y2)    // Straight horizontal line
  1480.     {
  1481.         register unsigned long     *longBaseAddr;
  1482.         register                 numLongBlits;
  1483.         unsigned long            longColor;
  1484.         
  1485.             // Fill longColor with color
  1486.         longColor = (color<<24) | (color<<16) | (color<<8) | (color);
  1487.         
  1488.         if (x2 < x1)
  1489.         {
  1490.             x1 = dstPoint.h;    // Swap x1 and x2 if they're
  1491.             x2 = srcPoint.h;    // in the wrong order.
  1492.         }
  1493.         
  1494.             // Make sure some part of the line is inside the frameRect
  1495.         if (y1 < dstFrameP->frameRect.top || y1 >= dstFrameP->frameRect.bottom)
  1496.             return;
  1497.         
  1498.         if (x1 < dstFrameP->frameRect.left)
  1499.             x1 = dstFrameP->frameRect.left;
  1500.         if (x2 >= dstFrameP->frameRect.right)
  1501.             x2 = dstFrameP->frameRect.right-1;
  1502.         
  1503.         dx = x2 - x1 + 1;    // dx = number of pixels in line
  1504.         if (dx > 0)    // Make sure there is a line first!
  1505.         {
  1506.             numLongBlits = (dx >> 2);
  1507.             longBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr + 
  1508.                     dstFrameP->scanLinePtrArray[y1] + x1);
  1509.             
  1510.             while (numLongBlits--)
  1511.             {
  1512.                 *(longBaseAddr)++ = longColor;
  1513.             }
  1514.             
  1515. #ifdef __MWERKS__  // Do it nicely
  1516.                 // Handle extra pixels at end of line
  1517.             if (dx & 0x2)
  1518.                 *((unsigned short *) longBaseAddr)++ = (unsigned short)longColor;
  1519.             if (dx & 0x1)
  1520.                 *((unsigned char *) longBaseAddr)++ = color;
  1521. #else     // Make Think C happy
  1522.                 // Handle extra pixels at end of line
  1523.             if (dx & 0x2)
  1524.             {
  1525.                 *((unsigned short *) longBaseAddr) = (unsigned short)longColor;
  1526.                 longBaseAddr = (unsigned long *)(((unsigned short *)longBaseAddr) + 1);
  1527.             }
  1528.             if (dx & 0x1)
  1529.             {
  1530.                 *((unsigned char *) longBaseAddr) = color;
  1531.                 longBaseAddr = (unsigned long *)(((unsigned char *)longBaseAddr) + 1);
  1532.             }
  1533. #endif
  1534.         }
  1535.     }
  1536. }
  1537.  
  1538.  
  1539. ///--------------------------------------------------------------------------------------
  1540. //  BPCopyStraightLine - Clipping is performed by function, since it's easy for a straight 
  1541. //    line. Assumes srcFrameP->frameRect and dstFrameP->frameRect are the same size!
  1542. ///--------------------------------------------------------------------------------------
  1543.  
  1544. SW_FUNC void BPCopyStraightLine(
  1545.     FramePtr srcFrameP, 
  1546.     FramePtr dstFrameP, 
  1547.     Point srcPoint, 
  1548.     Point dstPoint)
  1549. {
  1550.     unsigned long    srcRowBytes = srcFrameP->frameRowBytes;
  1551.     unsigned long    dstRowBytes = dstFrameP->frameRowBytes;
  1552.     short            x1 = srcPoint.h, y1 = srcPoint.v, 
  1553.                     x2 = dstPoint.h, y2 = dstPoint.v;
  1554.     short            dx, dy;
  1555.  
  1556.     
  1557.     if (x1 == x2)        // Straight vertical line
  1558.     {
  1559.         register Ptr    srcBaseAddr;
  1560.         register Ptr    dstBaseAddr;
  1561.         
  1562.         if (y2 < y1)
  1563.         {
  1564.             y1 = dstPoint.v;    // Swap y1 and y2 if they're
  1565.             y2 = srcPoint.v;    // in the wrong order.
  1566.         }
  1567.         
  1568.             // Make sure some part of the line is inside the frameRect
  1569.         if (x1 < dstFrameP->frameRect.left || x1 >= dstFrameP->frameRect.right)
  1570.             return;
  1571.         
  1572.             // Clip the ends of the line
  1573.         if (y1 < dstFrameP->frameRect.top)
  1574.             y1 = dstFrameP->frameRect.top;
  1575.         if (y2 >= dstFrameP->frameRect.bottom)
  1576.             y2 = dstFrameP->frameRect.bottom-1;
  1577.         
  1578.         dy = y2 - y1 + 1;    // dy = number of pixels in line
  1579.         if (dy > 0)    // Make sure there is a line first!
  1580.         {
  1581.             srcBaseAddr = srcFrameP->frameBaseAddr + srcFrameP->scanLinePtrArray[y1] + x1;
  1582.             dstBaseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
  1583.             
  1584.             *dstBaseAddr = *srcBaseAddr;    // Copy the first pixel
  1585.             
  1586.             while (--dy)
  1587.             {
  1588.                 srcBaseAddr += srcRowBytes;
  1589.                 dstBaseAddr += dstRowBytes;
  1590.                 *dstBaseAddr = *srcBaseAddr;
  1591.             }
  1592.         }
  1593.     }
  1594.     else if (y1 == y2)    // Straight horizontal line
  1595.     {
  1596.         register unsigned long    *srcBaseAddr;
  1597.         register unsigned long    *dstBaseAddr;
  1598.         register                 numLongBlits;
  1599.         
  1600.         if (x2 < x1)
  1601.         {
  1602.             x1 = dstPoint.h;    // Swap x1 and x2 if they're
  1603.             x2 = srcPoint.h;    // in the wrong order.
  1604.         }
  1605.         
  1606.             // Make sure some part of the line is inside the frameRect
  1607.         if (y1 < dstFrameP->frameRect.top || y1 >= dstFrameP->frameRect.bottom)
  1608.             return;
  1609.         
  1610.             // Clip the ends of the line
  1611.         if (x1 < dstFrameP->frameRect.left)
  1612.             x1 = dstFrameP->frameRect.left;
  1613.         if (x2 >= dstFrameP->frameRect.right)
  1614.             x2 = dstFrameP->frameRect.right-1;
  1615.         
  1616.         dx = x2 - x1 + 1;    // dx = number of pixels in line
  1617.         if (dx > 0)        // Make sure there is a line first!
  1618.         {
  1619.             numLongBlits = (dx >> 2);
  1620.             srcBaseAddr = (unsigned long *)(srcFrameP->frameBaseAddr + 
  1621.                     srcFrameP->scanLinePtrArray[y1] + x1);
  1622.             dstBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr + 
  1623.                     dstFrameP->scanLinePtrArray[y1] + x1);
  1624.             
  1625.             while (numLongBlits--)
  1626.             {
  1627.                 *(dstBaseAddr)++ = *(srcBaseAddr)++;
  1628.             }
  1629.                 
  1630.         
  1631. #ifdef __MWERKS__  // Do it nicely
  1632.                 // Handle extra pixels at end of line
  1633.             if (dx & 0x2)
  1634.                 *((unsigned short *) dstBaseAddr)++ = *((unsigned short *) srcBaseAddr)++;
  1635.             if (dx & 0x1)
  1636.                 *((unsigned char *) dstBaseAddr)++ = *((unsigned char *) srcBaseAddr)++;
  1637. #else     // Make Think C happy
  1638.                 // Handle extra pixels at end of line
  1639.             if (dx & 0x2)
  1640.             {
  1641.                 *((unsigned short *) dstBaseAddr) = *((unsigned short *) srcBaseAddr);
  1642.                 dstBaseAddr = (unsigned long *)(((unsigned short *)dstBaseAddr) + 1);
  1643.                 srcBaseAddr = (unsigned long *)(((unsigned short *)srcBaseAddr) + 1);
  1644.             }
  1645.             if (dx & 0x1)
  1646.             {
  1647.                 *((unsigned char *) dstBaseAddr) = *((unsigned char *) srcBaseAddr);
  1648.                 dstBaseAddr = (unsigned long *)(((unsigned char *)dstBaseAddr) + 1);
  1649.                 srcBaseAddr = (unsigned long *)(((unsigned char *)srcBaseAddr) + 1);
  1650.             }
  1651. #endif
  1652.         }
  1653.     }
  1654. }
  1655.  
  1656.  
  1657. ///--------------------------------------------------------------------------------------
  1658. //  BlitStraightWrappingLine - No clipping performed by function.
  1659. //    Assumes srcFrameP->frameRect and dstFrameP->frameRect are the same size!
  1660. ///--------------------------------------------------------------------------------------
  1661.  
  1662. SW_FUNC void BlitStraightWrappingLine(
  1663.     FramePtr dstFrameP, 
  1664.     Point srcPoint, 
  1665.     Point dstPoint, 
  1666.     Byte color)
  1667. {
  1668.     unsigned long    rowBytes = dstFrameP->frameRowBytes;
  1669.     short            x1 = srcPoint.h, y1 = srcPoint.v, 
  1670.                     x2 = dstPoint.h, y2 = dstPoint.v;
  1671.     short            dx, dy;
  1672.     
  1673.     if (x1 == x2)        // Straight vertical line
  1674.     {
  1675.         register Ptr    baseAddr;
  1676.         short            y3, y4;        // Second half of wrapped line
  1677.         
  1678.         if (y2 < y1)
  1679.         {
  1680.             y1 = dstPoint.v;    // Swap y1 and y2 if they're
  1681.             y2 = srcPoint.v;    // in the wrong order.
  1682.         }
  1683.         
  1684.             // Wrap line horizontally if necessary before we start (only done once)
  1685.             // Remember x1 and x2 are the same, and x2 isn't used.
  1686.         if (x1 < dstFrameP->frameRect.left)
  1687.             x1 += dstFrameP->frameRect.right;    
  1688.         else if (x1 >= dstFrameP->frameRect.right)
  1689.             x1 -= dstFrameP->frameRect.right;
  1690.         
  1691.             // Now we check to see if the line wraps vertically, in which case we
  1692.             // split it into two lines before drawing it.
  1693.         if (y1 < dstFrameP->frameRect.top)
  1694.         {
  1695.             if (y2 < dstFrameP->frameRect.top)
  1696.                 y4 = y2 + dstFrameP->frameRect.bottom;
  1697.             else
  1698.                 y4 = dstFrameP->frameRect.bottom-1;
  1699.             
  1700.             y3 = y1 + dstFrameP->frameRect.bottom;
  1701.             y1 = dstFrameP->frameRect.top;
  1702.         }
  1703.         else if (y2 >= dstFrameP->frameRect.bottom)
  1704.         {
  1705.             if (y1 >= dstFrameP->frameRect.bottom)
  1706.                 y3 = y1 - dstFrameP->frameRect.bottom;
  1707.             else
  1708.                 y3 = dstFrameP->frameRect.top;
  1709.             
  1710.             y4 = y2 - dstFrameP->frameRect.bottom;
  1711.             y2 = dstFrameP->frameRect.bottom-1;
  1712.         }
  1713.         else
  1714.         {
  1715.             y3 = 0;        // The formula for no second line
  1716.             y4 = -1;
  1717.         }
  1718.         
  1719.             // -----Draw the first line-----
  1720.         dy = y2 - y1 + 1;    // dy = number of pixels in line
  1721.         if (dy > 0)        // Make sure there is a line first!
  1722.         {
  1723.             baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
  1724.             *baseAddr = color;
  1725.             
  1726.             while(--dy)
  1727.             {
  1728.                 baseAddr += rowBytes;
  1729.                 *baseAddr = color;
  1730.             } 
  1731.         }
  1732.         
  1733.         
  1734.             // -----Draw the second line-----
  1735.         dy = y4 - y3 + 1;    // dy = number of pixels in line
  1736.         if (dy > 0)            // Make sure there is a line first!
  1737.         {
  1738.             baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y3] + x1;
  1739.             *baseAddr = color;
  1740.             
  1741.             while(--dy)
  1742.             {
  1743.                 baseAddr += rowBytes;
  1744.                 *baseAddr = color;
  1745.             }
  1746.         }
  1747.     }
  1748.     else if (y1 == y2)    // Straight horizontal line
  1749.     {
  1750.         register unsigned long     *longBaseAddr;
  1751.         register                 numLongBlits;
  1752.         unsigned long            longColor;
  1753.         short                    x3, x4;        // Second half of wrapped line
  1754.         
  1755.             // Fill longColor with color
  1756.         longColor = (color<<24) | (color<<16) | (color<<8) | (color);
  1757.         
  1758.         if (x2 < x1)
  1759.         {
  1760.             x1 = dstPoint.h;    // Swap x1 and x2 if they're
  1761.             x2 = srcPoint.h;    // in the wrong order.
  1762.         }
  1763.         
  1764.             // Wrap line vertically if necessary before we start (only done once)
  1765.             // Remember y1 and y2 are the same, and y2 isn't used.
  1766.         if (y1 < dstFrameP->frameRect.top)
  1767.             y1 += dstFrameP->frameRect.bottom;    
  1768.         else if (y1 >= dstFrameP->frameRect.bottom)
  1769.             y1 -= dstFrameP->frameRect.bottom;
  1770.         
  1771.             // Now we check to see if the line wraps horizontally, in which case we
  1772.             // split it into two lines before drawing it.
  1773.         if (x1 < dstFrameP->frameRect.left)
  1774.         {
  1775.             if (x2 < dstFrameP->frameRect.left)
  1776.                 x4 = x2 + dstFrameP->frameRect.right;
  1777.             else
  1778.                 x4 = dstFrameP->frameRect.right-1;
  1779.             
  1780.             x3 = x1 + dstFrameP->frameRect.right;
  1781.             x1 = dstFrameP->frameRect.left;
  1782.         }
  1783.         else if (x2 >= dstFrameP->frameRect.right)
  1784.         {
  1785.             if (x1 >= dstFrameP->frameRect.right)
  1786.                 x3 = x1 - dstFrameP->frameRect.right;
  1787.             else
  1788.                 x3 = dstFrameP->frameRect.left;
  1789.             
  1790.             x4 = x2 - dstFrameP->frameRect.right;
  1791.             x2 = dstFrameP->frameRect.right-1;
  1792.         }
  1793.         else
  1794.         {
  1795.             x3 = 0;        // The formula for no second line
  1796.             x4 = -1;
  1797.         }
  1798.         
  1799.             // ----Draw the first line----
  1800.         dx = x2 - x1 + 1;    // dx = number of pixels in line
  1801.         if (dx > 0)            // Make sure there is a line first!
  1802.         {
  1803.             numLongBlits = (dx >> 2);
  1804.             longBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr + 
  1805.                     dstFrameP->scanLinePtrArray[y1] + x1);
  1806.             
  1807.             while (numLongBlits--)
  1808.             {
  1809.                 *(longBaseAddr)++ = longColor;
  1810.             }
  1811.             
  1812. #ifdef __MWERKS__  // Do it nicely
  1813.                 // Handle extra pixels at end of line
  1814.             if (dx & 0x2)
  1815.                 *((unsigned short *) longBaseAddr)++ = (unsigned short)longColor;
  1816.             if (dx & 0x1)
  1817.                 *((unsigned char *) longBaseAddr)++ = color;
  1818. #else     // Make Think C happy
  1819.                 // Handle extra pixels at end of line
  1820.             if (dx & 0x2)
  1821.             {
  1822.                 *((unsigned short *) longBaseAddr) = (unsigned short)longColor;
  1823.                 longBaseAddr = (unsigned long *)(((unsigned short *)longBaseAddr) + 1);
  1824.             }
  1825.             if (dx & 0x1)
  1826.             {
  1827.                 *((unsigned char *) longBaseAddr) = color;
  1828.                 longBaseAddr = (unsigned long *)(((unsigned char *)longBaseAddr) + 1);
  1829.             }
  1830. #endif
  1831.         }
  1832.         
  1833.         
  1834.             // ----Draw the second line----
  1835.         dx = x4 - x3 + 1;    // dx = number of pixels in line
  1836.         if (dx > 0)            // Make sure there is a line first!
  1837.         {
  1838.             numLongBlits = (dx >> 2);
  1839.             longBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr + 
  1840.                     dstFrameP->scanLinePtrArray[y1] + x3);
  1841.             
  1842.             while (numLongBlits--)
  1843.             {
  1844.                 *(longBaseAddr)++ = longColor;
  1845.             }
  1846.         
  1847. #ifdef __MWERKS__  // Do it nicely
  1848.                 // Handle extra pixels at end of line
  1849.             if (dx & 0x2)
  1850.                 *((unsigned short *) longBaseAddr)++ = (unsigned short)longColor;
  1851.             if (dx & 0x1)
  1852.                 *((unsigned char *) longBaseAddr)++ = color;
  1853. #else     // Make Think C happy
  1854.                 // Handle extra pixels at end of line
  1855.             if (dx & 0x2)
  1856.             {
  1857.                 *((unsigned short *) longBaseAddr) = (unsigned short)longColor;
  1858.                 longBaseAddr = (unsigned long *)(((unsigned short *)longBaseAddr) + 1);
  1859.             }
  1860.             if (dx & 0x1)
  1861.             {
  1862.                 *((unsigned char *) longBaseAddr) = color;
  1863.                 longBaseAddr = (unsigned long *)(((unsigned char *)longBaseAddr) + 1);
  1864.             }
  1865. #endif
  1866.         }
  1867.     }
  1868. }
  1869.  
  1870.  
  1871. ///--------------------------------------------------------------------------------------
  1872. //  BPCopyStraightWrappingLine  - No clipping performed by function. 
  1873. //    Assumes srcFrameP->frameRect and dstFrameP->frameRect are the same size!
  1874. ///--------------------------------------------------------------------------------------
  1875.  
  1876. SW_FUNC void BPCopyStraightWrappingLine(
  1877.     FramePtr srcFrameP, 
  1878.     FramePtr dstFrameP, 
  1879.     Point srcPoint, 
  1880.     Point dstPoint)
  1881. {
  1882.     unsigned long    srcRowBytes = srcFrameP->frameRowBytes;
  1883.     unsigned long    dstRowBytes = dstFrameP->frameRowBytes;
  1884.     short            x1 = srcPoint.h, y1 = srcPoint.v, 
  1885.                     x2 = dstPoint.h, y2 = dstPoint.v;
  1886.     short            dx, dy;
  1887.     
  1888.     if (x1 == x2)        // Straight vertical line
  1889.     {
  1890.         register Ptr    srcBaseAddr, dstBaseAddr;
  1891.         short            y3, y4;        // Second half of wrapped line
  1892.         
  1893.         if (y2 < y1)
  1894.         {
  1895.             y1 = dstPoint.v;    // Swap y1 and y2 if they're
  1896.             y2 = srcPoint.v;    // in the wrong order.
  1897.         }
  1898.         
  1899.             // Wrap line horizontally if necessary before we start (only done once)
  1900.             // Remember x1 and x2 are the same, and x2 isn't used.
  1901.         if (x1 < dstFrameP->frameRect.left)
  1902.             x1 += dstFrameP->frameRect.right;    
  1903.         else if (x1 >= dstFrameP->frameRect.right)
  1904.             x1 -= dstFrameP->frameRect.right;
  1905.         
  1906.             // Now we check to see if the line wraps vertically, in which case we
  1907.             // split it into two lines before drawing it.
  1908.         if (y1 < dstFrameP->frameRect.top)
  1909.         {
  1910.             if (y2 < dstFrameP->frameRect.top)
  1911.                 y4 = y2 + dstFrameP->frameRect.bottom;
  1912.             else
  1913.                 y4 = dstFrameP->frameRect.bottom-1;
  1914.             
  1915.             y3 = y1 + dstFrameP->frameRect.bottom;
  1916.             y1 = dstFrameP->frameRect.top;
  1917.         }
  1918.         else if (y2 >= dstFrameP->frameRect.bottom)
  1919.         {
  1920.             if (y1 >= dstFrameP->frameRect.bottom)
  1921.                 y3 = y1 - dstFrameP->frameRect.bottom;
  1922.             else
  1923.                 y3 = dstFrameP->frameRect.top;
  1924.             
  1925.             y4 = y2 - dstFrameP->frameRect.bottom;
  1926.             y2 = dstFrameP->frameRect.bottom-1;
  1927.         }
  1928.         else
  1929.         {
  1930.             y3 = 0;        // The formula for no second line
  1931.             y4 = -1;
  1932.         }
  1933.         
  1934.             // -----Draw the first line-----
  1935.         dy = y2 - y1 + 1;    // dy = number of pixels in line
  1936.         if (dy > 0)            // Make sure there is a line first!
  1937.         {
  1938.             srcBaseAddr = srcFrameP->frameBaseAddr + srcFrameP->scanLinePtrArray[y1] + x1;
  1939.             dstBaseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
  1940.             
  1941.             *dstBaseAddr = *srcBaseAddr;    // Copy the first pixel
  1942.             
  1943.             while (--dy)
  1944.             {
  1945.                 srcBaseAddr += srcRowBytes;
  1946.                 dstBaseAddr += dstRowBytes;
  1947.                 *dstBaseAddr = *srcBaseAddr;
  1948.             }
  1949.         }
  1950.         
  1951.         
  1952.             // -----Draw the second line-----
  1953.         dy = y4 - y3 + 1;    // dy = number of pixels in line
  1954.         if (dy > 0)            // Make sure there is a line first!
  1955.         {
  1956.             srcBaseAddr = srcFrameP->frameBaseAddr + srcFrameP->scanLinePtrArray[y3] + x1;
  1957.             dstBaseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y3] + x1;
  1958.             
  1959.             *dstBaseAddr = *srcBaseAddr;    // Copy the first pixel
  1960.             
  1961.             while (--dy)
  1962.             {
  1963.                 srcBaseAddr += srcRowBytes;
  1964.                 dstBaseAddr += dstRowBytes;
  1965.                 *dstBaseAddr = *srcBaseAddr;
  1966.             }
  1967.         }
  1968.     }
  1969.     else if (y1 == y2)    // Straight horizontal line
  1970.     {
  1971.         register unsigned long     *srcBaseAddr, *dstBaseAddr;
  1972.         register                 numLongBlits;
  1973.         short                    x3, x4;        // Second half of wrapped line
  1974.         
  1975.         if (x2 < x1)
  1976.         {
  1977.             x1 = dstPoint.h;    // Swap x1 and x2 if they're
  1978.             x2 = srcPoint.h;    // in the wrong order.
  1979.         }
  1980.         
  1981.             // Wrap line vertically if necessary before we start (only done once)
  1982.             // Remember y1 and y2 are the same, and y2 isn't used.
  1983.         if (y1 < dstFrameP->frameRect.top)
  1984.             y1 += dstFrameP->frameRect.bottom;    
  1985.         else if (y1 >= dstFrameP->frameRect.bottom)
  1986.             y1 -= dstFrameP->frameRect.bottom;
  1987.         
  1988.             // Now we check to see if the line wraps horizontally, in which case we
  1989.             // split it into two lines before drawing it.
  1990.         if (x1 < dstFrameP->frameRect.left)
  1991.         {
  1992.             if (x2 < dstFrameP->frameRect.left)
  1993.                 x4 = x2 + dstFrameP->frameRect.right;
  1994.             else
  1995.                 x4 = dstFrameP->frameRect.right-1;
  1996.             
  1997.             x3 = x1 + dstFrameP->frameRect.right;
  1998.             x1 = dstFrameP->frameRect.left;
  1999.         }
  2000.         else if (x2 >= dstFrameP->frameRect.right)
  2001.         {
  2002.             if (x1 >= dstFrameP->frameRect.right)
  2003.                 x3 = x1 - dstFrameP->frameRect.right;
  2004.             else
  2005.                 x3 = dstFrameP->frameRect.left;
  2006.             
  2007.             x4 = x2 - dstFrameP->frameRect.right;
  2008.             x2 = dstFrameP->frameRect.right-1;
  2009.         }
  2010.         else
  2011.         {
  2012.             x3 = 0;        // The formula for no second line
  2013.             x4 = -1;
  2014.         }
  2015.         
  2016.             // ----Draw the first line----
  2017.         dx = x2 - x1 + 1;    // dx = number of pixels in line
  2018.         if (dx > 0)            // Make sure there is a line first!
  2019.         {
  2020.             numLongBlits = (dx >> 2);
  2021.             srcBaseAddr = (unsigned long *)(srcFrameP->frameBaseAddr + 
  2022.                     srcFrameP->scanLinePtrArray[y1] + x1);
  2023.             dstBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr + 
  2024.                     dstFrameP->scanLinePtrArray[y1] + x1);
  2025.             
  2026.             while (numLongBlits--)
  2027.             {
  2028.                 *(dstBaseAddr)++ = *(srcBaseAddr)++;
  2029.             }
  2030.             
  2031.         
  2032. #ifdef __MWERKS__  // Do it nicely
  2033.                 // Handle extra pixels at end of line
  2034.             if (dx & 0x2)
  2035.                 *((unsigned short *) dstBaseAddr)++ = *((unsigned short *) srcBaseAddr)++;
  2036.             if (dx & 0x1)
  2037.                 *((unsigned char *) dstBaseAddr)++ = *((unsigned char *) srcBaseAddr)++;
  2038. #else     // Make Think C happy
  2039.                 // Handle extra pixels at end of line
  2040.             if (dx & 0x2)
  2041.             {
  2042.                 *((unsigned short *) dstBaseAddr) = *((unsigned short *) srcBaseAddr);
  2043.                 dstBaseAddr = (unsigned long *)(((unsigned short *)dstBaseAddr) + 1);
  2044.                 srcBaseAddr = (unsigned long *)(((unsigned short *)srcBaseAddr) + 1);
  2045.             }
  2046.             if (dx & 0x1)
  2047.             {
  2048.                 *((unsigned char *) dstBaseAddr) = *((unsigned char *) srcBaseAddr);
  2049.                 dstBaseAddr = (unsigned long *)(((unsigned char *)dstBaseAddr) + 1);
  2050.                 srcBaseAddr = (unsigned long *)(((unsigned char *)srcBaseAddr) + 1);
  2051.             }
  2052. #endif
  2053.         }
  2054.         
  2055.         
  2056.             // ----Draw the second line----
  2057.         dx = x4 - x3 + 1;    // dx = number of pixels in line
  2058.         if (dx > 0)            // Make sure there is a line first!
  2059.         {
  2060.             numLongBlits = (dx >> 2);
  2061.             srcBaseAddr = (unsigned long *)(srcFrameP->frameBaseAddr + 
  2062.                     srcFrameP->scanLinePtrArray[y1] + x3);
  2063.             dstBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr + 
  2064.                     dstFrameP->scanLinePtrArray[y1] + x3);
  2065.             
  2066.             while (numLongBlits--)
  2067.             {
  2068.                 *(dstBaseAddr)++ = *(srcBaseAddr)++;
  2069.             }
  2070.             
  2071.         
  2072. #ifdef __MWERKS__  // Do it nicely
  2073.                 // Handle extra pixels at end of line
  2074.             if (dx & 0x2)
  2075.                 *((unsigned short *) dstBaseAddr)++ = *((unsigned short *) srcBaseAddr)++;
  2076.             if (dx & 0x1)
  2077.                 *((unsigned char *) dstBaseAddr)++ = *((unsigned char *) srcBaseAddr)++;
  2078. #else     // Make Think C happy
  2079.                 // Handle extra pixels at end of line
  2080.             if (dx & 0x2)
  2081.             {
  2082.                 *((unsigned short *) dstBaseAddr) = *((unsigned short *) srcBaseAddr);
  2083.                 dstBaseAddr = (unsigned long *)(((unsigned short *)dstBaseAddr) + 1);
  2084.                 srcBaseAddr = (unsigned long *)(((unsigned short *)srcBaseAddr) + 1);
  2085.             }
  2086.             if (dx & 0x1)
  2087.             {
  2088.                 *((unsigned char *) dstBaseAddr) = *((unsigned char *) srcBaseAddr);
  2089.                 dstBaseAddr = (unsigned long *)(((unsigned char *)dstBaseAddr) + 1);
  2090.                 srcBaseAddr = (unsigned long *)(((unsigned char *)srcBaseAddr) + 1);
  2091.             }
  2092. #endif
  2093.         }
  2094.     }
  2095. }
  2096.  
  2097.